// Copyright 2023 The Lynx Authors. All rights reserved.
// Licensed under the Apache License Version 2.0 that can be found in the
// LICENSE file in the root directory of this source tree.

#include "core/renderer/css/css_color.h"

#include "core/renderer/css/parser/css_string_parser.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"

namespace lynx {
namespace tasm {
namespace test {

const std::unordered_map<std::string, CSSColor>& NamedColors() {
  static const base::NoDestructor<std::unordered_map<std::string, CSSColor>>
      colors{{
          {"transparent", {0, 0, 0, 0}},
          {"aliceblue", {240, 248, 255, 1}},
          {"antiquewhite", {250, 235, 215, 1}},
          {"aqua", {0, 255, 255, 1}},
          {"aquamarine", {127, 255, 212, 1}},
          {"azure", {240, 255, 255, 1}},
          {"beige", {245, 245, 220, 1}},
          {"bisque", {255, 228, 196, 1}},
          {"black", {0, 0, 0, 1}},
          {"blanchedalmond", {255, 235, 205, 1}},
          {"blue", {0, 0, 255, 1}},
          {"blueviolet", {138, 43, 226, 1}},
          {"brown", {165, 42, 42, 1}},
          {"burlywood", {222, 184, 135, 1}},
          {"cadetblue", {95, 158, 160, 1}},
          {"chartreuse", {127, 255, 0, 1}},
          {"chocolate", {210, 105, 30, 1}},
          {"coral", {255, 127, 80, 1}},
          {"cornflowerblue", {100, 149, 237, 1}},
          {"cornsilk", {255, 248, 220, 1}},
          {"crimson", {220, 20, 60, 1}},
          {"cyan", {0, 255, 255, 1}},
          {"darkblue", {0, 0, 139, 1}},
          {"darkcyan", {0, 139, 139, 1}},
          {"darkgoldenrod", {184, 134, 11, 1}},
          {"darkgray", {169, 169, 169, 1}},
          {"darkgreen", {0, 100, 0, 1}},
          {"darkgrey", {169, 169, 169, 1}},
          {"darkkhaki", {189, 183, 107, 1}},
          {"darkmagenta", {139, 0, 139, 1}},
          {"darkolivegreen", {85, 107, 47, 1}},
          {"darkorange", {255, 140, 0, 1}},
          {"darkorchid", {153, 50, 204, 1}},
          {"darkred", {139, 0, 0, 1}},
          {"darksalmon", {233, 150, 122, 1}},
          {"darkseagreen", {143, 188, 143, 1}},
          {"darkslateblue", {72, 61, 139, 1}},
          {"darkslategray", {47, 79, 79, 1}},
          {"darkslategrey", {47, 79, 79, 1}},
          {"darkturquoise", {0, 206, 209, 1}},
          {"darkviolet", {148, 0, 211, 1}},
          {"deeppink", {255, 20, 147, 1}},
          {"deepskyblue", {0, 191, 255, 1}},
          {"dimgray", {105, 105, 105, 1}},
          {"dimgrey", {105, 105, 105, 1}},
          {"dodgerblue", {30, 144, 255, 1}},
          {"firebrick", {178, 34, 34, 1}},
          {"floralwhite", {255, 250, 240, 1}},
          {"forestgreen", {34, 139, 34, 1}},
          {"fuchsia", {255, 0, 255, 1}},
          {"gainsboro", {220, 220, 220, 1}},
          {"ghostwhite", {248, 248, 255, 1}},
          {"gold", {255, 215, 0, 1}},
          {"goldenrod", {218, 165, 32, 1}},
          {"gray", {128, 128, 128, 1}},
          {"green", {0, 128, 0, 1}},
          {"greenyellow", {173, 255, 47, 1}},
          {"grey", {128, 128, 128, 1}},
          {"honeydew", {240, 255, 240, 1}},
          {"hotpink", {255, 105, 180, 1}},
          {"indianred", {205, 92, 92, 1}},
          {"indigo", {75, 0, 130, 1}},
          {"ivory", {255, 255, 240, 1}},
          {"khaki", {240, 230, 140, 1}},
          {"lavender", {230, 230, 250, 1}},
          {"lavenderblush", {255, 240, 245, 1}},
          {"lawngreen", {124, 252, 0, 1}},
          {"lemonchiffon", {255, 250, 205, 1}},
          {"lightblue", {173, 216, 230, 1}},
          {"lightcoral", {240, 128, 128, 1}},
          {"lightcyan", {224, 255, 255, 1}},
          {"lightgoldenrodyellow", {250, 250, 210, 1}},
          {"lightgray", {211, 211, 211, 1}},
          {"lightgreen", {144, 238, 144, 1}},
          {"lightgrey", {211, 211, 211, 1}},
          {"lightpink", {255, 182, 193, 1}},
          {"lightsalmon", {255, 160, 122, 1}},
          {"lightseagreen", {32, 178, 170, 1}},
          {"lightskyblue", {135, 206, 250, 1}},
          {"lightslategray", {119, 136, 153, 1}},
          {"lightslategrey", {119, 136, 153, 1}},
          {"lightsteelblue", {176, 196, 222, 1}},
          {"lightyellow", {255, 255, 224, 1}},
          {"lime", {0, 255, 0, 1}},
          {"limegreen", {50, 205, 50, 1}},
          {"linen", {250, 240, 230, 1}},
          {"magenta", {255, 0, 255, 1}},
          {"maroon", {128, 0, 0, 1}},
          {"mediumaquamarine", {102, 205, 170, 1}},
          {"mediumblue", {0, 0, 205, 1}},
          {"mediumorchid", {186, 85, 211, 1}},
          {"mediumpurple", {147, 112, 219, 1}},
          {"mediumseagreen", {60, 179, 113, 1}},
          {"mediumslateblue", {123, 104, 238, 1}},
          {"mediumspringgreen", {0, 250, 154, 1}},
          {"mediumturquoise", {72, 209, 204, 1}},
          {"mediumvioletred", {199, 21, 133, 1}},
          {"midnightblue", {25, 25, 112, 1}},
          {"mintcream", {245, 255, 250, 1}},
          {"mistyrose", {255, 228, 225, 1}},
          {"moccasin", {255, 228, 181, 1}},
          {"navajowhite", {255, 222, 173, 1}},
          {"navy", {0, 0, 128, 1}},
          {"oldlace", {253, 245, 230, 1}},
          {"olive", {128, 128, 0, 1}},
          {"olivedrab", {107, 142, 35, 1}},
          {"orange", {255, 165, 0, 1}},
          {"orangered", {255, 69, 0, 1}},
          {"orchid", {218, 112, 214, 1}},
          {"palegoldenrod", {238, 232, 170, 1}},
          {"palegreen", {152, 251, 152, 1}},
          {"paleturquoise", {175, 238, 238, 1}},
          {"palevioletred", {219, 112, 147, 1}},
          {"papayawhip", {255, 239, 213, 1}},
          {"peachpuff", {255, 218, 185, 1}},
          {"peru", {205, 133, 63, 1}},
          {"pink", {255, 192, 203, 1}},
          {"plum", {221, 160, 221, 1}},
          {"powderblue", {176, 224, 230, 1}},
          {"purple", {128, 0, 128, 1}},
          {"red", {255, 0, 0, 1}},
          {"rosybrown", {188, 143, 143, 1}},
          {"royalblue", {65, 105, 225, 1}},
          {"saddlebrown", {139, 69, 19, 1}},
          {"salmon", {250, 128, 114, 1}},
          {"sandybrown", {244, 164, 96, 1}},
          {"seagreen", {46, 139, 87, 1}},
          {"seashell", {255, 245, 238, 1}},
          {"sienna", {160, 82, 45, 1}},
          {"silver", {192, 192, 192, 1}},
          {"skyblue", {135, 206, 235, 1}},
          {"slateblue", {106, 90, 205, 1}},
          {"slategray", {112, 128, 144, 1}},
          {"slategrey", {112, 128, 144, 1}},
          {"snow", {255, 250, 250, 1}},
          {"springgreen", {0, 255, 127, 1}},
          {"steelblue", {70, 130, 180, 1}},
          {"tan", {210, 180, 140, 1}},
          {"teal", {0, 128, 128, 1}},
          {"thistle", {216, 191, 216, 1}},
          {"tomato", {255, 99, 71, 1}},
          {"turquoise", {64, 224, 208, 1}},
          {"violet", {238, 130, 238, 1}},
          {"wheat", {245, 222, 179, 1}},
          {"white", {255, 255, 255, 1}},
          {"whitesmoke", {245, 245, 245, 1}},
          {"yellow", {255, 255, 0, 1}},
          {"yellowgreen", {154, 205, 50, 1}},
      }};
  return *colors;
}

TEST(CSSColor, Keywords) {
  for (const auto& it : NamedColors()) {
    CSSColor color;
    EXPECT_TRUE(CSSColor::ParseNamedColor(it.first, color));
    EXPECT_EQ(color, it.second);
  }
}

TEST(CSSColor, Parse) {
  auto color_str = "not color";
  CSSColor color;
  EXPECT_FALSE(CSSColor::Parse(color_str, color));

  color_str = "red";
  EXPECT_TRUE(CSSColor::Parse(color_str, color));
  EXPECT_EQ(color.Cast(), 0xffff0000);

  color_str = "#00ff00";
  EXPECT_TRUE(CSSColor::Parse(color_str, color));
  EXPECT_EQ(color.Cast(), 0xff00ff00);

  color_str = "#056b";
  EXPECT_TRUE(CSSColor::Parse(color_str, color));
  EXPECT_EQ(color.Cast(), 0xbb005566);

  color_str = "#090a";
  EXPECT_TRUE(CSSColor::Parse(color_str, color));
  EXPECT_EQ(color.Cast(), 0xaa009900);

  color_str = "#abcd";
  EXPECT_TRUE(CSSColor::Parse(color_str, color));
  EXPECT_EQ(color.Cast(), 0xddaabbcc);

  color_str = "#hello0";
  EXPECT_FALSE(CSSColor::Parse(color_str, color));

  color_str = "#00ff00ee";
  EXPECT_TRUE(CSSColor::Parse(color_str, color));
  EXPECT_EQ(color.Cast(), 0xee00ff00);

  color_str = "rgb(0,0,255)";
  EXPECT_TRUE(CSSColor::Parse(color_str, color));
  EXPECT_EQ(color.Cast(), 0xff0000ff);

  color_str = "rgb(2000,-1,255)";
  EXPECT_TRUE(CSSColor::Parse(color_str, color));
  EXPECT_EQ(color.Cast(), 0xffff00ff);

  color_str = "rgb(0, 0, 255)";
  EXPECT_TRUE(CSSColor::Parse(color_str, color));
  EXPECT_EQ(color.Cast(), 0xff0000ff);

  color_str = "rgb(100%, 0, 100%)";
  EXPECT_TRUE(CSSColor::Parse(color_str, color));
  EXPECT_EQ(color.Cast(), 0xffff00ff);

  color_str = "rgba(0, 0, 255, 100)";
  EXPECT_TRUE(CSSColor::Parse(color_str, color));
  EXPECT_EQ(color.Cast(), 0xff0000ff);

  color_str = "hsl(240, 100%, 50%)";
  EXPECT_TRUE(CSSColor::Parse(color_str, color));
  EXPECT_EQ(color.Cast(), 0xff0000ff);

  color_str = "hsla(240, 100%, 50%, 0.3)";
  EXPECT_TRUE(CSSColor::Parse(color_str, color));
  EXPECT_EQ(color.Cast(), 0x4c0000ff);

  color_str = "#errors";
  EXPECT_FALSE(CSSColor::Parse(color_str, color));
}

}  // namespace test
}  // namespace tasm
}  // namespace lynx
